Date: Fri Dec 13 12:54:45 2019
Scientist: Ran Yin
Sequencing (Waksman): Dibyendu Kumar
Statistics: Davit Sargsyan
Principal Investigator: Ah-Ng Kong
# Taxonomic Ranks:
# **K**ing **P**hillip **C**an n**O**t **F**ind **G**reen **S**ocks
# * Kingdom
# * Phylum
# * Class
# * Order
# * Family
# * Genus
# * Species
# options(stringsAsFactors = FALSE,
# scipen = 999)
# # Increase mmemory size to 64 Gb----
# invisible(utils::memory.limit(65536))
# str(knitr::opts_chunk$get())
# # NOTE: the below does not work!
# knitr::opts_chunk$set(echo = FALSE,
# message = FALSE,
# warning = FALSE,
# error = FALSE)
# require(knitr)
# require(kableExtra)
require(phyloseq)
Loading required package: phyloseq
# require(shiny)
require(data.table)
Loading required package: data.table
data.table 1.12.2 using 18 threads (see ?getDTthreads). Latest news: r-datatable.com
require(ggplot2)
Loading required package: ggplot2
require(plotly)
Loading required package: plotly
Attaching package: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
require(DT)
Loading required package: DT
require(lmerTest)
Loading required package: lmerTest
Loading required package: lme4
Loading required package: Matrix
Attaching package: ‘lmerTest’
The following object is masked from ‘package:lme4’:
lmer
The following object is masked from ‘package:stats’:
step
source("source/functions_may2019.R")
# On Windows set multithread=FALSE----
mt <- TRUE
Introduction
C57BL/6 wild-type (WT) and Nrf-2 double-knock-out (KO -/-) mice were given 2-week microbiome stabilization process using AIN93M diet and 8 more weeks to treat with either AIN93M or AIN93M 5% PEITC diet. Fecal samples were collected weekly, immediately frozen in liquid nitrogen and stored at -80oC. Serum, cecal, colon epithelial and whole colon tissues at week 10 were also collected for further analyses. Baseline, week 1 and 4 fecal samples were selected for 16s rRNA sequencing.
This document examines results from the WT mice samples.
We will attampt to answer the following questions:
1. Did microbiome change over time?
2. Was microbiome affected by diet?
3. Was there a difference between the KO and WT?
4. If there was a change in microbiome composition, what functional changes did it carry? What are the essential functions of the bacteria affected by the treatment and how can this be shown in vivo (metabolites, inflammation markers, etc.)?
Data preprocessing
Raw Data
FastQ files were downloaded from this Rutgers Box location. A total of 144 files (2 per sample, pair-ended) and a pair of undetermined reads were downloaded.
Samples
ps_sep2019@sam_data$Genotype_Week <- paste(ps_sep2019@sam_data$genotype,
ps_sep2019@sam_data$time,
sep = "_")
ps_sep2019@sam_data$ID <- factor(paste0(ps_sep2019@sam_data$mice_num,
ps_sep2019@sam_data$cage))
ps_sep2019@sam_data$TREATMENT <- paste0(ps_sep2019@sam_data$DSS,
ps_sep2019@sam_data$PEITC,
ps_sep2019@sam_data$cranberry)
ps_sep2019@sam_data$TREATMENT <- factor(ps_sep2019@sam_data$TREATMENT,
levels = c("000",
"100",
"110",
"101"),
labels = c("Naive",
"DSS",
"DSS+PEITC",
"DSS+Cranberry"))
samples <- ps_sep2019@sam_data
datatable(samples,
options = list(pageLength = nrow(samples)))
Prune data
The OTUs were mapped to Bacteria (96.07%), Eukaryota (2.95%) and Archea (0.03%) kingdoms, and 75 OTUs (0.95%) undefined.
The total of 7,867 unique sequences were found. Out of those, 7,558 were mapped to bacterial genomes.
dim(ps_sep2019@otu_table@.Data)
[1] 72 7867
# Remove OTU not mapped to Bacteria
ps0 <- subset_taxa(ps_sep2019,
Kingdom == "Bacteria")
dim(ps0@otu_table@.Data)
[1] 72 7558
These 7,247 belonged to 12 Phyla. 311 of the OTUs (or 4.11% of bacterial OTUs) could not be mapped to a Phyla.
t2 <- data.table(table(tax_table(ps0)[, "Phylum"],
exclude = NULL))
t2$V1[is.na(t2$V1)] <- "Unknown"
setorder(t2, -N)
t2[, pct := N/sum(N)]
setorder(t2, -N)
colnames(t2) <- c("Phylum",
"Number of OTUs",
"Percent of OTUs")
datatable(t2,
rownames = FALSE,
caption = "Number of Bacterial OTUs by Phylum",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t2))) %>%
formatCurrency(columns = 2,
currency = "",
mark = ",",
digits = 0) %>%
formatPercentage(columns = 3,
digits = 2)
OTU table (first 10 rows)
Total counts per sample (i.e. sequencing depth)
t1 <- colSums(otu[, 7:ncol(otu)])
t1 <- data.table(SAMPLE_NAME = names(t1),
Total = t1)
t2 <- data.table(SAMPLE_NAME = rownames(samples),
ID = samples$ID,
CAGE = samples$cage,
TREATMENT = samples$TREATMENT,
Genotype = samples$genotype,
WEEK = samples$time)
smpl <- merge(t1,
t2,
by = "SAMPLE_NAME")
p1 <- ggplot(smpl,
aes(x = SAMPLE_NAME,
y = Total,
fill = TREATMENT,
colour = WEEK)) +
facet_wrap(~ Genotype,
scale = "free_x") +
geom_bar(stat = "identity") +
scale_x_discrete("") +
scale_y_continuous("Number of Reads") +
scale_fill_discrete("Treatment") +
theme(axis.text.x = element_text(angle = 45,
hjust = 1))
ggplotly(p1)
Richness (Alpha diversity)
Shannon’s diversity index was calculated for each sample and ploted over time using the 7,764 from the 13 Phylum above.
p1 <- plot_richness(ps0,
x = "time",
measures = "Shannon") +
facet_wrap(~ genotype) +
geom_line(aes(group = ID),
color = "black") +
geom_point(aes(fill = TREATMENT),
shape = 21,
size = 3,
color = "black") +
scale_x_discrete("") +
theme(axis.text.x = element_text(angle = 30,
hjust = 1,
vjust = 1))
ggplotly(p = p1,
tooltip = c("ID",
"value"))
p1 <- p1 +
scale_fill_discrete("") +
theme(legend.position = "top")
tiff(filename = "tmp/shannon.tiff",
height = 4,
width = 5,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
Test if the richness changed between the baseline and the week 8.
tmp <- data.table(SAMPLE_NAME = p1$data$samples,
Shannon = p1$data$value)
tmp <- merge(smpl,
tmp,
by = "SAMPLE_NAME")
tmp$TREATMENT <- factor(tmp$TREATMENT,
levels = c("DSS",
"Naive",
"DSS+PEITC",
"DSS+Cranberry"))
tmp <- droplevels(tmp[WEEK != "week1"])
m1 <- lm(Shannon ~ WEEK*(TREATMENT + Genotype),
# offset = Total,
data = tmp)
summary(m1)
Call:
lm(formula = Shannon ~ WEEK * (TREATMENT + Genotype), data = tmp)
Residuals:
Min 1Q Median 3Q Max
-0.316186 -0.091027 0.007886 0.110704 0.293230
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.94987 0.07064 84.233 < 2e-16 ***
WEEKweek8 0.01158 0.09989 0.116 0.9084
TREATMENTNaive 0.14581 0.08935 1.632 0.1109
TREATMENTDSS+PEITC -0.03923 0.08935 -0.439 0.6631
TREATMENTDSS+Cranberry -0.22582 0.08935 -2.527 0.0158 *
Genotypewidetype -0.54156 0.06318 -8.572 2.06e-10 ***
WEEKweek8:TREATMENTNaive 0.01181 0.12636 0.093 0.9261
WEEKweek8:TREATMENTDSS+PEITC 0.01652 0.12636 0.131 0.8966
WEEKweek8:TREATMENTDSS+Cranberry 0.21535 0.12636 1.704 0.0965 .
WEEKweek8:Genotypewidetype 0.23085 0.08935 2.584 0.0137 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.1548 on 38 degrees of freedom
Multiple R-squared: 0.7845, Adjusted R-squared: 0.7335
F-statistic: 15.37 on 9 and 38 DF, p-value: 3.671e-10
m2 <- lmer(Shannon ~ WEEK*(TREATMENT + Genotype) + (1 | ID),
# offset = Total,
data = tmp)
summary(m2)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Shannon ~ WEEK * (TREATMENT + Genotype) + (1 | ID)
Data: tmp
REML criterion at convergence: -22.2
Scaled residuals:
Min 1Q Median 3Q Max
-1.53721 -0.47495 0.06753 0.44489 1.53874
Random effects:
Groups Name Variance Std.Dev.
ID (Intercept) 0.01259 0.1122
Residual 0.01136 0.1066
Number of obs: 48, groups: ID, 24
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 5.94987 0.07064 29.76837 84.233 < 2e-16 ***
WEEKweek8 0.01158 0.06879 19.00000 0.168 0.86814
TREATMENTNaive 0.14581 0.08935 29.76837 1.632 0.11322
TREATMENTDSS+PEITC -0.03923 0.08935 29.76837 -0.439 0.66379
TREATMENTDSS+Cranberry -0.22582 0.08935 29.76837 -2.527 0.01704 *
Genotypewidetype -0.54156 0.06318 29.76837 -8.572 1.55e-09 ***
WEEKweek8:TREATMENTNaive 0.01181 0.08701 19.00000 0.136 0.89350
WEEKweek8:TREATMENTDSS+PEITC 0.01652 0.08701 19.00000 0.190 0.85139
WEEKweek8:TREATMENTDSS+Cranberry 0.21535 0.08701 19.00000 2.475 0.02291 *
WEEKweek8:Genotypewidetype 0.23085 0.06152 19.00000 3.752 0.00135 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) WEEKw8 TREATMENTN TREATMENTDSS+P TREATMENTDSS+C Gntypw WEEK8:TREATMENTN
WEEKweek8 -0.487
TREATMENTNv -0.632 0.308
TREATMENTDSS+P -0.632 0.308 0.500
TREATMENTDSS+C -0.632 0.308 0.500 0.500
Gentypwdtyp -0.447 0.218 0.000 0.000 0.000
WEEK8:TREATMENTN 0.308 -0.632 -0.487 -0.243 -0.243 0.000
WEEK8:TREATMENTDSS+P 0.308 -0.632 -0.243 -0.487 -0.243 0.000 0.500
WEEK8:TREATMENTDSS+C 0.308 -0.632 -0.243 -0.243 -0.487 0.000 0.500
WEEKwk8:Gnt 0.218 -0.447 0.000 0.000 0.000 -0.487 0.000
WEEK8:TREATMENTDSS+P WEEK8:TREATMENTDSS+C
WEEKweek8
TREATMENTNv
TREATMENTDSS+P
TREATMENTDSS+C
Gentypwdtyp
WEEK8:TREATMENTN
WEEK8:TREATMENTDSS+P
WEEK8:TREATMENTDSS+C 0.500
WEEKwk8:Gnt 0.000 0.000
The results showed that…
Remove unmapped OTUs
The 311 unmapped OTUs were removed from further analysis (with 7,247 OTUs left).
ps1 <- subset_taxa(ps0,
!is.na(Phylum))
dim(ps1@otu_table@.Data)
[1] 72 7247
Relative abundance (%) at Phylum level
Remove phyla with relative abundance of >= 1% in less than 10% of samples.
t1 <- data.table(Phylum = ra_p$Phylum,
`Number of Samples` = rowSums(ra_p[, 2:ncol(ra_p)] >= 0.01))
t1$`Percent Samples` <- t1$`Number of Samples`/72
setorder(t1, -`Number of Samples`)
datatable(t1,
rownames = FALSE,
caption = "Taxonomic count table",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t1))) %>%
formatPercentage(columns = 3,
digits = 1)
We will remove Chlamydiae from this analysis.
[1] "Firmicutes, Bacteroidetes, Proteobacteria, Verrucomicrobia, Epsilonbacteraeota, Actinobacteria, Deferribacteres, Patescibacteria, Cyanobacteria"
XX OTUs, down from YY OTUs in the previous table.
Relative Abundance in Samples at Different Taxonomic Ranks
1. Class
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Class,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_class_over_time.tiff",
height = 5,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)

p1 <- ggplot(mu,
aes(x = x,
y = Class,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_class_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
2. Order
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Order,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_Order_over_time.tiff",
height = 5,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)

p1 <- ggplot(mu,
aes(x = x,
y = Order,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_Order_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
3. Family
NOTE: only the first 24 families had large enough counts - ploting only them.
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
mu <- droplevels(mu[levels(mu$Family)[1:24], ])
Error in `[.data.table`(mu, levels(mu$Family)[1:24], ) :
When i is a data.table (or character vector), the columns to join by must be specified either using 'on=' argument (see ?data.table) or by keying x (i.e. sorted, and, marked as sorted, see ?setkey). Keyed joins might have further speed benefits on very large data due to x being sorted in RAM.
LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpemF0aW9uIG9mIFdUIGFuZCBOcmYyIEtPICgtLy0pIEJMNiBQRUlUQyBvciBDcmFuYmVycnkgVHJlYXRlZCBNaWNlIDE2UyBNaWNyb2Jpb21lIERhdGEgQW5hbHlzaXMsIFNlcHRlbWJlciAyMDE5IEJhdGNoIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCkRhdGU6IGByIGRhdGUoKWAgICAgIApTY2llbnRpc3Q6IFtSYW4gWWluXShtYWlsdG86cnkxNDdAc2NhcmxldG1haWwucnV0Z2Vycy5lZHUpICAgICAgClNlcXVlbmNpbmcgKFdha3NtYW4pOiBbRGlieWVuZHUgS3VtYXJdKG1haWx0bzpka0B3YWtzbWFuLnJ1dGdlcnMuZWR1KSAgICAgIApTdGF0aXN0aWNzOiBbRGF2aXQgU2FyZ3N5YW5dKG1haWx0bzpzYXJnZGF2aWRAZ21haWwuY29tKSAgICAgIApQcmluY2lwYWwgSW52ZXN0aWdhdG9yOiBbQWgtTmcgS29uZ10obWFpbHRvOmtvbmd0QHBoYXJtYWN5LnJ1dGdlcnMuZWR1KSAKCmBgYHt9CiMgVGF4b25vbWljIFJhbmtzOgojICoqSyoqaW5nICoqUCoqaGlsbGlwICoqQyoqYW4gbioqTyoqdCAqKkYqKmluZCAqKkcqKnJlZW4gKipTKipvY2tzCiMgKiBLaW5nZG9tICAgICAgICAgICAgICAgIAojICogUGh5bHVtICAgICAgICAgICAgICAgICAgICAKIyAqIENsYXNzICAgICAgICAgICAgICAgICAgIAojICogT3JkZXIgICAgICAgICAgICAgICAgICAgCiMgKiBGYW1pbHkgICAgIAojICogR2VudXMgICAgIAojICogU3BlY2llcyAgCmBgYAoKYGBge3Igc2V0dXB9CiMgb3B0aW9ucyhzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UsCiMgICAgICAgICBzY2lwZW4gPSA5OTkpCgojICMgSW5jcmVhc2UgbW1lbW9yeSBzaXplIHRvIDY0IEdiLS0tLQojIGludmlzaWJsZSh1dGlsczo6bWVtb3J5LmxpbWl0KDY1NTM2KSkKCgojIHN0cihrbml0cjo6b3B0c19jaHVuayRnZXQoKSkKIyAjIE5PVEU6IHRoZSBiZWxvdyBkb2VzIG5vdCB3b3JrIQojIGtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UsIAojICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsCiMgICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwKIyAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBGQUxTRSkKCiMgcmVxdWlyZShrbml0cikKIyByZXF1aXJlKGthYmxlRXh0cmEpCnJlcXVpcmUocGh5bG9zZXEpCiMgcmVxdWlyZShzaGlueSkKCnJlcXVpcmUoZGF0YS50YWJsZSkKcmVxdWlyZShnZ3Bsb3QyKQpyZXF1aXJlKHBsb3RseSkKcmVxdWlyZShEVCkKcmVxdWlyZShsbWVyVGVzdCkKCnNvdXJjZSgic291cmNlL2Z1bmN0aW9uc19tYXkyMDE5LlIiKQoKIyBPbiBXaW5kb3dzIHNldCBtdWx0aXRocmVhZD1GQUxTRS0tLS0KbXQgPC0gVFJVRQpgYGAKCiMgSW50cm9kdWN0aW9uCkM1N0JMLzYgd2lsZC10eXBlIChXVCkgYW5kIE5yZi0yIGRvdWJsZS1rbm9jay1vdXQgKEtPIC0vLSkgbWljZSB3ZXJlIGdpdmVuIDItd2VlayBtaWNyb2Jpb21lIHN0YWJpbGl6YXRpb24gcHJvY2VzcyB1c2luZyBBSU45M00gZGlldCBhbmQgOCBtb3JlIHdlZWtzIHRvIHRyZWF0IHdpdGggZWl0aGVyIEFJTjkzTSBvciBBSU45M00gNSUgUEVJVEMgZGlldC4gRmVjYWwgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCB3ZWVrbHksIGltbWVkaWF0ZWx5IGZyb3plbiBpbiBsaXF1aWQgbml0cm9nZW4gYW5kIHN0b3JlZCBhdCAtODBeb15DLiBTZXJ1bSwgY2VjYWwsIGNvbG9uIGVwaXRoZWxpYWwgYW5kIHdob2xlIGNvbG9uIHRpc3N1ZXMgYXQgd2VlayAxMCB3ZXJlIGFsc28gY29sbGVjdGVkIGZvciBmdXJ0aGVyIGFuYWx5c2VzLiBCYXNlbGluZSwgd2VlayAxIGFuZCA0IGZlY2FsIHNhbXBsZXMgd2VyZSBzZWxlY3RlZCBmb3IgMTZzIHJSTkEgc2VxdWVuY2luZy4gIAogIApUaGlzIGRvY3VtZW50IGV4YW1pbmVzIHJlc3VsdHMgZnJvbSB0aGUgV1QgbWljZSBzYW1wbGVzLiAgCiAgCldlIHdpbGwgYXR0YW1wdCB0byBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6ICAKMS4gRGlkIG1pY3JvYmlvbWUgY2hhbmdlIG92ZXIgdGltZT8gIAoyLiBXYXMgbWljcm9iaW9tZSBhZmZlY3RlZCBieSBkaWV0PyAgCjMuIFdhcyB0aGVyZSBhIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgS08gYW5kIFdUPyAgCjQuIElmIHRoZXJlIHdhcyBhIGNoYW5nZSBpbiBtaWNyb2Jpb21lIGNvbXBvc2l0aW9uLCB3aGF0IGZ1bmN0aW9uYWwgY2hhbmdlcyBkaWQgaXQgY2Fycnk/IFdoYXQgYXJlIHRoZSBlc3NlbnRpYWwgZnVuY3Rpb25zIG9mIHRoZSBiYWN0ZXJpYSBhZmZlY3RlZCBieSB0aGUgdHJlYXRtZW50IGFuZCBob3cgY2FuIHRoaXMgYmUgc2hvd24gaW4gdml2byAobWV0YWJvbGl0ZXMsIGluZmxhbW1hdGlvbiBtYXJrZXJzLCBldGMuKT8KCiMgRGF0YSBwcmVwcm9jZXNzaW5nCiMjIFJhdyBEYXRhIApGYXN0USBmaWxlcyB3ZXJlIGRvd25sb2FkZWQgZnJvbSBbdGhpcyBSdXRnZXJzIEJveCBsb2NhdGlvbl0oaHR0cHM6Ly9ydXRnZXJzLmFwcC5ib3guY29tL2ZvbGRlci85MDE0MzQ2MjI5MSkuIEEgdG90YWwgb2YgMTQ0IGZpbGVzICgyIHBlciBzYW1wbGUsIHBhaXItZW5kZWQpIGFuZCBhIHBhaXIgb2YgdW5kZXRlcm1pbmVkIHJlYWRzIHdlcmUgZG93bmxvYWRlZC4gCgojIyBTY3JpcHQKVGhpcyBzY3JpcHQgKCoqKm5yZjJ1YmlvbWVfZGFkYTJfc2VwMjAxOV92MS5SbWQqKiopIHdhcyBkZXZlbG9wZWQgdXNpbmcgW0RBREEyIFBpcGVsaW5lIFR1dG9yaWFsICgxLjEyKV0oaHR0cHM6Ly9iZW5qam5lYi5naXRodWIuaW8vZGFkYTIvdHV0b3JpYWwuaHRtbCkgd2l0aCB0aXBzIGFuZCB0cmlja3MgZnJvbSB0aGUgW1VuaXZlcnNpdHkgb2YgTWFyeWxhbmQgU2hvb2wgb2YgTWVkaWNpbmUgSW5zdGl0dXRlIGZvciBHZW5vbWUgU2NpZW5jZXMgKElHUyldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvKSBbTWljcm9iaW9tZSBBbmFseXNpcyBXb3Jrc2hvcCAoQXByaWwgOC0xMSwgMjAxOSldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvZWR1Y2F0aW9uL3drc2hwX21ldGFnZW5vbWUucGhwKS4gVGhlIG91dHB1dCBvZiB0aGUgREFEQTIgc2NyaXB0ICgqKipkYXRhX21heTIwMTkvcHNfc2VwMjAxOS5SRGF0YSoqKikgaXMgZXhwbG9yZWQgaW4gdGhpcyBkb2N1bWVudC4KCiMgTWV0YSBkYXRhOiBzYW1wbGUgZGVzY3JpcHRpb24KYGBge3IgZGF0YX0KIyBMb2FkIGRhdGEtLS0tCiMgQ291bnRzCmxvYWQoImRhdGFfc2VwMjAxOS9wc19zZXAyMDE5LlJEYXRhIikKCiMgVGF4b25vbXkKbG9hZCgiZGF0YV9zZXAyMDE5L3RheGEuUkRhdGEiKQp0YXhhIDwtIGRhdGEudGFibGUoc2VxMTZzID0gcm93bmFtZXModGF4YSksCiAgICAgICAgICAgICAgICAgICB0YXhhKQpgYGAKCioqTk9URTogY29ycmVjdGlvbiB0byB0aGUgbWV0YS1kYXRhISoqICgxMS8xNS8yMDE5KQpgYGB7ciBjb3JyZWN0X21ldGFfZGF0YX0KY29ycmVjdF9zYW1wbGVzIDwtIGZyZWFkKCJkYXRhX3NlcDIwMTkvMTZzIG1ldGFkYXRhIFNlcC0yMDE5LmNzdiIpCnBzX3NlcDIwMTlAc2FtX2RhdGEkRFNTIDwtIGNvcnJlY3Rfc2FtcGxlcyREU1MKYGBgCgojIFNhbXBsZXMKYGBge3Igc2FtcGxlc30KcHNfc2VwMjAxOUBzYW1fZGF0YSRHZW5vdHlwZV9XZWVrIDwtIHBhc3RlKHBzX3NlcDIwMTlAc2FtX2RhdGEkZ2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJHRpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpCnBzX3NlcDIwMTlAc2FtX2RhdGEkSUQgPC0gZmFjdG9yKHBhc3RlMChwc19zZXAyMDE5QHNhbV9kYXRhJG1pY2VfbnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNfc2VwMjAxOUBzYW1fZGF0YSRjYWdlKSkKCnBzX3NlcDIwMTlAc2FtX2RhdGEkVFJFQVRNRU5UIDwtIHBhc3RlMChwc19zZXAyMDE5QHNhbV9kYXRhJERTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzX3NlcDIwMTlAc2FtX2RhdGEkUEVJVEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJGNyYW5iZXJyeSkKcHNfc2VwMjAxOUBzYW1fZGF0YSRUUkVBVE1FTlQgPC0gZmFjdG9yKHBzX3NlcDIwMTlAc2FtX2RhdGEkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJOYWl2ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkKCnNhbXBsZXMgPC0gcHNfc2VwMjAxOUBzYW1fZGF0YQpkYXRhdGFibGUoc2FtcGxlcywKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSBucm93KHNhbXBsZXMpKSkKYGBgCgojIFBydW5lIGRhdGEKVGhlIE9UVXMgd2VyZSBtYXBwZWQgdG8gQmFjdGVyaWEgKDk2LjA3JSksIEV1a2FyeW90YSAoMi45NSUpIGFuZCBBcmNoZWEgKDAuMDMlKSBraW5nZG9tcywgYW5kICA3NSBPVFVzICgwLjk1JSkgdW5kZWZpbmVkLiAKCmBgYHtyIGNoZWNrX21hcHBpbmdfa2luZ2RvbSwgd2FybmluZyA9IEZBTFNFLCBlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KdDEgPC0gZGF0YS50YWJsZSh0YWJsZSh0YXhfdGFibGUocHNfc2VwMjAxOSlbLCAiS2luZ2RvbSJdLAogICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGUgPSBOVUxMKSkKdDEkVjFbaXMubmEodDEkVjEpXSA8LSAiVW5rbm93biIKCnQxWywgcGN0IDo9IE4vc3VtKE4pXQpzZXRvcmRlcih0MSwgLU4pCgpjb2xuYW1lcyh0MSkgPC0gYygiS2luZ2RvbSIsCiAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgT1RVcyIsCiAgICAgICAgICAgICAgICAgICJQZXJjZW50IG9mIE9UVXMiKQpkYXRhdGFibGUodDEsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJOdW1iZXIgb2YgT1RVcyBieSBLaW5nZG9tIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQxKSkpICU+JQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSAyLAogICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gIiIsCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwKICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKSAlPiUKICBmb3JtYXRQZXJjZW50YWdlKGNvbHVtbnMgPSAzLAogICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikKYGBgCgpUaGUgdG90YWwgb2YgNyw4NjcgdW5pcXVlIHNlcXVlbmNlcyB3ZXJlIGZvdW5kLiBPdXQgb2YgdGhvc2UsIDcsNTU4IHdlcmUgbWFwcGVkIHRvIGJhY3RlcmlhbCBnZW5vbWVzLiAKCmBgYHtyIGtlZXBfYmFjdGVyaWF9CmRpbShwc19zZXAyMDE5QG90dV90YWJsZUAuRGF0YSkKCiMgUmVtb3ZlIE9UVSBub3QgbWFwcGVkIHRvIEJhY3RlcmlhCnBzMCA8LSBzdWJzZXRfdGF4YShwc19zZXAyMDE5LCAKICAgICAgICAgICAgICAgICAgIEtpbmdkb20gPT0gIkJhY3RlcmlhIikKZGltKHBzMEBvdHVfdGFibGVALkRhdGEpCmBgYAogIApUaGVzZSA3LDI0NyBiZWxvbmdlZCB0byAxMiBQaHlsYS4gMzExIG9mIHRoZSBPVFVzIChvciA0LjExJSBvZiBiYWN0ZXJpYWwgT1RVcykgY291bGQgbm90IGJlIG1hcHBlZCB0byBhIFBoeWxhLgoKYGBge3IgcGh5bHVtX21hcHBpbmd9CnQyIDwtIGRhdGEudGFibGUodGFibGUodGF4X3RhYmxlKHBzMClbLCAiUGh5bHVtIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlID0gTlVMTCkpCnQyJFYxW2lzLm5hKHQyJFYxKV0gPC0gIlVua25vd24iCnNldG9yZGVyKHQyLCAtTikKdDJbLCBwY3QgOj0gTi9zdW0oTildCnNldG9yZGVyKHQyLCAtTikKCmNvbG5hbWVzKHQyKSA8LSBjKCJQaHlsdW0iLAogICAgICAgICAgICAgICAgICAiTnVtYmVyIG9mIE9UVXMiLAogICAgICAgICAgICAgICAgICAiUGVyY2VudCBvZiBPVFVzIikKCmRhdGF0YWJsZSh0MiwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIk51bWJlciBvZiBCYWN0ZXJpYWwgT1RVcyBieSBQaHlsdW0iLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3codDIpKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDIsCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDApICU+JQogIGZvcm1hdFBlcmNlbnRhZ2UoY29sdW1ucyA9IDMsCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQpgYGAKCiMgT1RVIHRhYmxlIChmaXJzdCAxMCByb3dzKQpgYGB7ciBvdHVfdGFibGUsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQpvdHUgPC0gZGF0YS50YWJsZShwczBAdGF4X3RhYmxlQC5EYXRhLAogICAgICAgICAgICAgICAgICB0KHBzMEBvdHVfdGFibGVALkRhdGEpKQpkYXRhdGFibGUoaGVhZChvdHUsIDEwKSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDc6MzYsCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDApCmBgYAoKIyBUb3RhbCBjb3VudHMgcGVyIHNhbXBsZSAoaS5lLiBzZXF1ZW5jaW5nIGRlcHRoKQpgYGB7ciBzZXFfZGVwdGgsIGZpZy53aWR0aCA9IDEwLGZpZy5oZWlnaHQgPSA1fQp0MSA8LSBjb2xTdW1zKG90dVssIDc6bmNvbChvdHUpXSkKdDEgPC0gZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IG5hbWVzKHQxKSwKICAgICAgICAgICAgICAgICBUb3RhbCA9IHQxKQoKdDIgPC0gZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IHJvd25hbWVzKHNhbXBsZXMpLAogICAgICAgICAgICAgICAgIElEID0gc2FtcGxlcyRJRCwKICAgICAgICAgICAgICAgICBDQUdFID0gc2FtcGxlcyRjYWdlLAogICAgICAgICAgICAgICAgIFRSRUFUTUVOVCA9IHNhbXBsZXMkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc2FtcGxlcyRnZW5vdHlwZSwKICAgICAgICAgICAgICAgICBXRUVLID0gc2FtcGxlcyR0aW1lKQoKc21wbCA8LSBtZXJnZSh0MSwKICAgICAgICAgICAgICB0MiwKICAgICAgICAgICAgICBieSA9ICJTQU1QTEVfTkFNRSIpCgpwMSA8LSBnZ3Bsb3Qoc21wbCwKICAgICAgICAgICAgIGFlcyh4ID0gU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgeSA9IFRvdGFsLAogICAgICAgICAgICAgICAgIGZpbGwgPSBUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgY29sb3VyID0gV0VFSykpICsKICBmYWNldF93cmFwKH4gR2Vub3R5cGUsCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3giKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCJOdW1iZXIgb2YgUmVhZHMiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgiVHJlYXRtZW50IikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkgCmdncGxvdGx5KHAxKQpgYGAKCiMgUmljaG5lc3MgKEFscGhhIGRpdmVyc2l0eSkKU2hhbm5vbidzIGRpdmVyc2l0eSBpbmRleCB3YXMgY2FsY3VsYXRlZCBmb3IgZWFjaCBzYW1wbGUgYW5kIHBsb3RlZCBvdmVyIHRpbWUgdXNpbmcgdGhlIDcsNzY0IGZyb20gdGhlIDEzIFBoeWx1bSBhYm92ZS4KCmBgYHtyIHJpY2huZXNzLCBmaWcud2lkdGggPSAxMCxmaWcuaGVpZ2h0ID0gNX0KcDEgPC0gcGxvdF9yaWNobmVzcyhwczAsCiAgICAgICAgICAgICAgICAgICAgeCA9ICJ0aW1lIiwgCiAgICAgICAgICAgICAgICAgICAgbWVhc3VyZXMgPSAiU2hhbm5vbiIpICsKICBmYWNldF93cmFwKH4gZ2Vub3R5cGUpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gSUQpLAogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX3BvaW50KGFlcyhmaWxsID0gVFJFQVRNRU5UKSwKICAgICAgICAgICAgIHNoYXBlID0gMjEsCiAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2anVzdCA9IDEpKQoKZ2dwbG90bHkocCA9IHAxLAogICAgICAgICB0b29sdGlwID0gYygiSUQiLAogICAgICAgICAgICAgICAgICAgICAidmFsdWUiKSkKCnAxIDwtIHAxICsgCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgiIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvc2hhbm5vbi50aWZmIiwKICAgICBoZWlnaHQgPSA0LAogICAgIHdpZHRoID0gNSwKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDEpCmdyYXBoaWNzLm9mZigpCmBgYAoKVGVzdCBpZiB0aGUgcmljaG5lc3MgY2hhbmdlZCBiZXR3ZWVuIHRoZSBiYXNlbGluZSBhbmQgdGhlIHdlZWsgOC4KYGBge3IgbG1fcmljaG5lc3N9CnRtcCA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gcDEkZGF0YSRzYW1wbGVzLAogICAgICAgICAgICAgICAgICBTaGFubm9uID0gcDEkZGF0YSR2YWx1ZSkKCnRtcCA8LSBtZXJnZShzbXBsLAogICAgICAgICAgICAgIHRtcCwKICAgICAgICAgICAgICBieSA9ICJTQU1QTEVfTkFNRSIpCgp0bXAkVFJFQVRNRU5UIDwtIGZhY3Rvcih0bXAkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJEU1MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOYWl2ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytQRUlUQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkKCnRtcCA8LSBkcm9wbGV2ZWxzKHRtcFtXRUVLICE9ICJ3ZWVrMSJdKQoKbTEgPC0gbG0oU2hhbm5vbiAgfiBXRUVLKihUUkVBVE1FTlQgKyBHZW5vdHlwZSksCiAgICAgICAgICMgb2Zmc2V0ID0gVG90YWwsCiAgICAgICAgIGRhdGEgPSB0bXApCnN1bW1hcnkobTEpCmBgYAoKYGBge3IgbG1lcl9yaWNobmVzc30KbTIgPC0gbG1lcihTaGFubm9uICB+IFdFRUsqKFRSRUFUTUVOVCArIEdlbm90eXBlKSArICgxIHwgSUQpLAogICAgICAgICAgICMgb2Zmc2V0ID0gVG90YWwsCiAgICAgICAgICAgZGF0YSA9IHRtcCkKc3VtbWFyeShtMikKYGBgCiAgClRoZSByZXN1bHRzIHNob3dlZCB0aGF0Li4uCiAgCiMgUmVtb3ZlIHVubWFwcGVkIE9UVXMKVGhlIDMxMSB1bm1hcHBlZCBPVFVzIHdlcmUgcmVtb3ZlZCBmcm9tIGZ1cnRoZXIgYW5hbHlzaXMgKHdpdGggNywyNDcgT1RVcyBsZWZ0KS4KYGBge3IgcmVtb3ZlX3VubWFwcGVkX290dV9waHlsdW19CnBzMSA8LSBzdWJzZXRfdGF4YShwczAsIAogICAgICAgICAgICAgICAgICAgIWlzLm5hKFBoeWx1bSkpCmRpbShwczFAb3R1X3RhYmxlQC5EYXRhKQpgYGAKCiMgQ291bnRzIGF0IFBoeWx1bSBsZXZlbApgYGB7ciBjb3VudHNfcCwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CmNvdW50c19wIDwtIGNvdW50c19ieV90YXhfcmFuayhkdDEgPSBvdHUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2dyX2J5ID0gIlBoeWx1bSIpCnNldG9yZGVyKGNvdW50c19wLCAtYDE5MDkxOS0wMWApCmRhdGF0YWJsZShjb3VudHNfcCwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3coY291bnRzX3ApKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDI6bmNvbChjb3VudHNfcCksCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDApCmBgYAoKIyBSZWxhdGl2ZSBhYnVuZGFuY2UgKCUpIGF0IFBoeWx1bSBsZXZlbApgYGB7ciByYV9wLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KcmFfcCA8LSByYV9ieV90YXhfcmFuayhjb3VudHMgPSBjb3VudHNfcCwKICAgICAgICAgICAgICAgICAgICAgICBwY3QgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBkaWdpdCA9IDQpCgpkYXRhdGFibGUocmFfcCwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3cocmFfcCkpKSAlPiUKICBmb3JtYXRQZXJjZW50YWdlKGNvbHVtbnMgPSAyOm5jb2woY291bnRzX3ApLAogICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikKYGBgCgpSZW1vdmUgcGh5bGEgd2l0aCByZWxhdGl2ZSBhYnVuZGFuY2Ugb2YgPj0gMSUgaW4gbGVzcyB0aGFuIDEwJSBvZiBzYW1wbGVzLgoKYGBge3IgcHJldl9wfQp0MSA8LSBkYXRhLnRhYmxlKFBoeWx1bSA9IHJhX3AkUGh5bHVtLAogICAgICAgICAgICAgICAgIGBOdW1iZXIgb2YgU2FtcGxlc2AgPSByb3dTdW1zKHJhX3BbLCAyOm5jb2wocmFfcCldID49IDAuMDEpKQp0MSRgUGVyY2VudCBTYW1wbGVzYCA8LSAgdDEkYE51bWJlciBvZiBTYW1wbGVzYC83MgoKc2V0b3JkZXIodDEsIC1gTnVtYmVyIG9mIFNhbXBsZXNgKQpkYXRhdGFibGUodDEsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQxKSkpICU+JQogIGZvcm1hdFBlcmNlbnRhZ2UoY29sdW1ucyA9IDMsCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAxKQpgYGAKCldlIHdpbGwgcmVtb3ZlIENobGFteWRpYWUgZnJvbSB0aGlzIGFuYWx5c2lzLgoKYGBge3Iga2VlcF82X3BoeWxhLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0Ka2VlcF9wIDwtIHQxJFBoeWx1bVt0MSRgUGVyY2VudCBTYW1wbGVzYCA+PSAwLjFdCiMgIyBLZWVwIGFsbAojIGtlZXBfcCA8LSB0MSRQaHlsdW0KCnBhc3RlMChrZWVwX3AsIGNvbGxhcHNlID0gIiwgIikKCnBzMSA8LSBzdWJzZXRfdGF4YShwczAsIAogICAgICAgICAgICAgICAgICAgUGh5bHVtICVpbiUga2VlcF9wICkKb3R1MSA8LSBkYXRhLnRhYmxlKHBzMUB0YXhfdGFibGVALkRhdGEsCiAgICAgICAgICAgICAgICAgICB0KHBzMUBvdHVfdGFibGVALkRhdGEpKQoKZGF0YXRhYmxlKGhlYWQob3R1MSwgMTApLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTApKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNzpuY29sKG90dTEpLAogICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gIiIsCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwKICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKQpgYGAKClhYIE9UVXMsIGRvd24gZnJvbSBZWSBPVFVzIGluIHRoZSBwcmV2aW91cyB0YWJsZS4KCgojIFJlbGF0aXZlIEFidW5kYW5jZSBpbiBTYW1wbGVzIGF0IERpZmZlcmVudCBUYXhvbm9taWMgUmFua3MKIyMgMS4gQ2xhc3MKYGBge3IgY291bnRzX2MsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQpjb3VudHNfYyA8LSBjb3VudHNfYnlfdGF4X3JhbmsoZHQxID0gb3R1MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiQ2xhc3MiKQpyYV9jIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19jKQoKdGF4LnJhbmtzIDwtIHVuaXF1ZShvdHUxWywgYygiUGh5bHVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2xhc3MiKV0pCgpyYV9jIDwtIG1lcmdlKHRheC5yYW5rcywKICAgICAgICAgICAgICByYV9jLAogICAgICAgICAgICAgIGJ5ID0gIkNsYXNzIikKCnRvdGFsIDwtIHJvd1N1bXMocmFfY1ssIDM6bmNvbChyYV9jKV0pCgpyYV9jJENsYXNzIDwtIGZhY3RvcihyYV9jJENsYXNzLAogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9jJENsYXNzW29yZGVyKHRvdGFsKV0pCgpyYV9jJFBoeWx1bSA8LSBmYWN0b3IocmFfYyRQaHlsdW0sCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfYyRQaHlsdW1bb3JkZXIodG90YWwpXSkpCnRtcCA8LSBtZWx0LmRhdGEudGFibGUoZGF0YSA9IHJhX2MsCiAgICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IDE6MiwKICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2MpLAogICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAiU0FNUExFX05BTUUiLAogICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLm5hbWUgPSAiUkEiKQoKdG1wIDwtIG1lcmdlKGRhdGEudGFibGUoU0FNUExFX05BTUUgPSBzbXBsJFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICBXRUVLID0gc21wbCRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBzbXBsJEdlbm90eXBlKSwKICAgICAgICAgICAgIHRtcCwKICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikKCiMgUGxvdCBzYW1wbGVzCnAxIDwtIGdncGxvdCh0bXAsCiAgICAgICAgICAgICBhZXMoeCA9IFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgIHkgPSBSQSwKICAgICAgICAgICAgICAgICBmaWxsID0gQ2xhc3MsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBQaHlsdW0pKSArCiAgZmFjZXRfd3JhcCh+IFdFRUsgKyBUUkVBVE1FTlQgKyBHZW5vdHlwZSwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLAogICAgICAgICAgICAgbnJvdyA9IDMpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQpnZ3Bsb3RseShwMSkKYGBgCgpgYGB7ciBtZWFuc19jLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQpscmEgPC0gcmFfbWVsdChyYSA9IHJhX2MsCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzbXBsLAogICAgICAgICAgICAgICBzYW1wbGVfbmFtZSA9ICJTQU1QTEVfTkFNRSIpCgptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gbGlzdChXZWVrID0gbHJhJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVhdG1lbnQgPSBscmEkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBscmEkR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyA9IGxyYSRDbGFzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTiA9ICJtZWFuIikpCm11WywgdG90YWwgOj0gc3VtKHgpLAogICBieSA9ICJDbGFzcyJdCnVsIDwtIHVuaXF1ZShtdVssIGMoIkNsYXNzIiwgCiAgICAgICAgICAgICAgICAgICAgInRvdGFsIildKQp1bCA8LSB1bFtvcmRlcih0b3RhbCksXQptdSRDbGFzcyA8LSBmYWN0b3IobXUkQ2xhc3MsCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IHVsJENsYXNzKQptdSR0b3RhbCA8LSBOVUxMCgpkYXRhdGFibGUobXUsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDUsCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpCmBgYAoKCmBgYHtyIG1lYW5zX2NfcDAsIGZpZy53aWR0aCA9IDksIGZpZy5oZWlnaHQgPSA3fQptdSRUcnRfR2Vub3R5cGUgPC0gZmFjdG9yKHBhc3RlKG11JFRyZWF0bWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICBtdSRHZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpKQoKcDAgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSBXZWVrLAogICAgICAgICAgICAgICAgIHkgPSB4LAogICAgICAgICAgICAgICAgIGdyb3VwID0gVHJ0X0dlbm90eXBlKSkgKwogIGZhY2V0X3dyYXAofiBDbGFzcywKICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsKICBnZW9tX2xpbmUocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpKSArCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksCiAgICAgICAgICAgICBzaGFwZSA9IDIxLAogICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvd3RfY2xhc3Nfb3Zlcl90aW1lLnRpZmYiLAogICAgIGhlaWdodCA9IDUsCiAgICAgd2lkdGggPSA3LAogICAgIHVuaXRzID0gImluIiwKICAgICByZXMgPSA2MDAsCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQpwcmludChwMCkKZ3JhcGhpY3Mub2ZmKCkKCnByaW50KHAwKQpgYGAKCgpgYGB7ciBtZWFuc19jX3AxLCBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gOX0KcDEgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSB4LAogICAgICAgICAgICAgICAgIHkgPSBDbGFzcywKICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwKICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwKICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpCgp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9jbGFzc19yYS50aWZmIiwKICAgICBoZWlnaHQgPSA0LAogICAgIHdpZHRoID0gNywKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDEpCmdyYXBoaWNzLm9mZigpCgpnZ3Bsb3RseShwMSkKYGBgCgojIyAyLiBPcmRlcgpgYGB7ciBjb3VudHNfbywgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTE1LGZpZy5oZWlnaHQ9MTV9CmNvdW50c19vIDwtIGNvdW50c19ieV90YXhfcmFuayhkdDEgPSBvdHUxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJPcmRlciIpCnJhX28gPC0gcmFfYnlfdGF4X3JhbmsoY291bnRzX28pCgp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPcmRlciIpXSkKCnJhX28gPC0gbWVyZ2UodGF4LnJhbmtzLAogICAgICAgICAgICAgIHJhX28sCiAgICAgICAgICAgICAgYnkgPSAiT3JkZXIiKQoKdG90YWwgPC0gcm93U3VtcyhyYV9vWywgMzpuY29sKHJhX28pXSkKCnJhX28kT3JkZXIgPC0gZmFjdG9yKHJhX28kT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHJhX28kT3JkZXJbb3JkZXIodG90YWwpXSkKCnJhX28kUGh5bHVtIDwtIGZhY3RvcihyYV9vJFBoeWx1bSwKICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHVuaXF1ZShyYV9vJFBoeWx1bVtvcmRlcih0b3RhbCldKSkKdG1wIDwtIG1lbHQuZGF0YS50YWJsZShkYXRhID0gcmFfbywKICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLAogICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IDM6bmNvbChjb3VudHNfbyksCiAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUubmFtZSA9ICJTQU1QTEVfTkFNRSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpCgp0bXAgPC0gbWVyZ2UoZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IHNtcGwkU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgIFRSRUFUTUVOVCA9IHNtcGwkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICBHZW5vdHlwZSA9IHNtcGwkR2Vub3R5cGUpLAogICAgICAgICAgICAgdG1wLAogICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQoKIyBQbG90IHNhbXBsZXMKcDEgPC0gZ2dwbG90KHRtcCwKICAgICAgICAgICAgIGFlcyh4ID0gU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgeSA9IFJBLAogICAgICAgICAgICAgICAgIGZpbGwgPSBPcmRlciwKICAgICAgICAgICAgICAgICBjb2xvciA9IFBoeWx1bSkpICsKICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLAogICAgICAgICAgICAgc2NhbGVzID0gImZyZWVfeCIsCiAgICAgICAgICAgICBucm93ID0gMykgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpCmdncGxvdGx5KHAxKQpgYGAKCmBgYHtyIG1lYW5zX28sIGVjaG8gPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CmxyYSA8LSByYV9tZWx0KHJhID0gcmFfbywKICAgICAgICAgICAgICAgc2FtcGxlcyA9IHNtcGwsCiAgICAgICAgICAgICAgIHNhbXBsZV9uYW1lID0gIlNBTVBMRV9OQU1FIikKCm11IDwtIGRhdGEudGFibGUoYWdncmVnYXRlKGxyYSRSQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBsaXN0KFdlZWsgPSBscmEkV0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5vdHlwZSA9IGxyYSRHZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9yZGVyID0gbHJhJE9yZGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkKbXVbLCB0b3RhbCA6PSBzdW0oeCksCiAgIGJ5ID0gIk9yZGVyIl0KdWwgPC0gdW5pcXVlKG11WywgYygiT3JkZXIiLCAKICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pCnVsIDwtIHVsW29yZGVyKHRvdGFsKSxdCm11JE9yZGVyIDwtIGZhY3RvcihtdSRPcmRlciwKICAgICAgICAgICAgICAgICAgIGxldmVsID0gdWwkT3JkZXIpCm11JHRvdGFsIDwtIE5VTEwKCmRhdGF0YWJsZShtdSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBsaXN0KGxpc3QoMywgJ2Rlc2MnKSkpKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNSwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikKYGBgCgpgYGB7ciBtZWFuc19vX3AwLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gN30KbXUkVHJ0X0dlbm90eXBlIDwtIGZhY3RvcihwYXN0ZShtdSRUcmVhdG1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIl8iKSkKCnAwIDwtIGdncGxvdChtdSwKICAgICAgICAgICAgIGFlcyh4ID0gV2VlaywKICAgICAgICAgICAgICAgICB5ID0geCwKICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsKICBmYWNldF93cmFwKH4gT3JkZXIsCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArCiAgZ2VvbV9saW5lKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKwogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBUcnRfR2Vub3R5cGUpLAogICAgICAgICAgICAgc2hhcGUgPSAyMSwKICAgICAgICAgICAgIHNpemUgPSAyLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCJSZWxhdGl2ZSBBYnVuZGFuY2UgKCUpIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkKCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X09yZGVyX292ZXJfdGltZS50aWZmIiwKICAgICBoZWlnaHQgPSA1LAogICAgIHdpZHRoID0gNywKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDApCmdyYXBoaWNzLm9mZigpCgpwcmludChwMCkKYGBgCgpgYGB7ciBtZWFuc19vX3AxLCBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gOX0KcDEgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSB4LAogICAgICAgICAgICAgICAgIHkgPSBPcmRlciwKICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwKICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwKICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpCgp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9PcmRlcl9yYS50aWZmIiwKICAgICBoZWlnaHQgPSA0LAogICAgIHdpZHRoID0gNywKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDEpCmdyYXBoaWNzLm9mZigpCgpnZ3Bsb3RseShwMSkKYGBgCgojIyAzLiBGYW1pbHkKYGBge3IgY291bnRzX2YsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQpjb3VudHNfZiA8LSBjb3VudHNfYnlfdGF4X3JhbmsoZHQxID0gb3R1MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiRmFtaWx5IikKcmFfZiA8LSByYV9ieV90YXhfcmFuayhjb3VudHNfZikKCnRheC5yYW5rcyA8LSB1bmlxdWUob3R1MVssIGMoIlBoeWx1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhbWlseSIpXSkKCnJhX2YgPC0gbWVyZ2UodGF4LnJhbmtzLAogICAgICAgICAgICAgIHJhX2YsCiAgICAgICAgICAgICAgYnkgPSAiRmFtaWx5IikKCnRvdGFsIDwtIHJvd1N1bXMocmFfZlssIDM6bmNvbChyYV9mKV0pCgpyYV9mJEZhbWlseSA8LSBmYWN0b3IocmFfZiRGYW1pbHksCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHJhX2YkRmFtaWx5W29yZGVyKHRvdGFsKV0pCgpyYV9mJFBoeWx1bSA8LSBmYWN0b3IocmFfZiRQaHlsdW0sCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfZiRQaHlsdW1bb3JkZXIodG90YWwpXSkpCnRtcCA8LSBtZWx0LmRhdGEudGFibGUoZGF0YSA9IHJhX2YsCiAgICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IDE6MiwKICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2YpLAogICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAiU0FNUExFX05BTUUiLAogICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLm5hbWUgPSAiUkEiKQoKdG1wIDwtIG1lcmdlKGRhdGEudGFibGUoU0FNUExFX05BTUUgPSBzbXBsJFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICBXRUVLID0gc21wbCRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBzbXBsJEdlbm90eXBlKSwKICAgICAgICAgICAgIHRtcCwKICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikKCiMgUGxvdCBzYW1wbGVzCnAxIDwtIGdncGxvdCh0bXAsCiAgICAgICAgICAgICBhZXMoeCA9IFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgIHkgPSBSQSwKICAgICAgICAgICAgICAgICBmaWxsID0gRmFtaWx5LAogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKwogIGZhY2V0X3dyYXAofiBXRUVLICsgVFJFQVRNRU5UICsgR2Vub3R5cGUsCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZV94IiwKICAgICAgICAgICAgIG5yb3cgPSAzKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkKZ2dwbG90bHkocDEpCmBgYAoKYGBge3IgbWVhbnNfZiwgZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KbHJhIDwtIHJhX21lbHQocmEgPSByYV9mLAogICAgICAgICAgICAgICBzYW1wbGVzID0gc21wbCwKICAgICAgICAgICAgICAgc2FtcGxlX25hbWUgPSAiU0FNUExFX05BTUUiKQoKbXUgPC0gZGF0YS50YWJsZShhZ2dyZWdhdGUobHJhJFJBLAogICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGxpc3QoV2VlayA9IGxyYSRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJlYXRtZW50ID0gbHJhJFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gbHJhJEdlbm90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5ID0gbHJhJEZhbWlseSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTiA9ICJtZWFuIikpCm11WywgdG90YWwgOj0gc3VtKHgpLAogICBieSA9ICJGYW1pbHkiXQp1bCA8LSB1bmlxdWUobXVbLCBjKCJGYW1pbHkiLCAKICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pCnVsIDwtIHVsW29yZGVyKHRvdGFsKSxdCm11JEZhbWlseSA8LSBmYWN0b3IobXUkRmFtaWx5LAogICAgICAgICAgICAgICAgICAgbGV2ZWwgPSB1bCRGYW1pbHkpCm11JHRvdGFsIDwtIE5VTEwKCmRhdGF0YWJsZShtdSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5ID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDUsCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpCmBgYAoKTk9URTogb25seSB0aGUgZmlyc3QgMjQgZmFtaWxpZXMgaGFkIGxhcmdlIGVub3VnaCBjb3VudHMgLSBwbG90aW5nIG9ubHkgdGhlbS4gIAogIApgYGB7ciBtZWFuc19mX3AwLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gN30KbXUkVHJ0X0dlbm90eXBlIDwtIGZhY3RvcihwYXN0ZShtdSRUcmVhdG1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIl8iKSkKbXUgPC0gZHJvcGxldmVscyhtdVtGYW1pbHkgPT0gbGV2ZWxzKG11JEZhbWlseSlbMToyNF0sIF0pCgpwMCA8LSBnZ3Bsb3QobXUsCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssCiAgICAgICAgICAgICAgICAgeSA9IHgsCiAgICAgICAgICAgICAgICAgZ3JvdXAgPSBUcnRfR2Vub3R5cGUpKSArCiAgZmFjZXRfd3JhcCh+IEZhbWlseSwKICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsKICBnZW9tX2xpbmUocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpKSArCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksCiAgICAgICAgICAgICBzaGFwZSA9IDIxLAogICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvd3RfRmFtaWx5X292ZXJfdGltZS50aWZmIiwKICAgICBoZWlnaHQgPSA1LAogICAgIHdpZHRoID0gNywKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDApCmdyYXBoaWNzLm9mZigpCgpwcmludChwMCkKYGBgCgojIFNlc3Npb24gSW5mb3JtYXRpb24KYGBge3IgaW5mbyxldmFsPVRSVUV9CnNlc3Npb25JbmZvKCkKYGBg